2

什么是Promise?

在说Promise之前, 不得不说一下,JavaScript的嵌套的回调函数

在JavaScript语言中, 无论是写浏览器端的各种事件回调、ajax回调,还是写Node.js上的业务逻辑,不得不面对的问题就是各种回调函数。回调函数
少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的。

个人认为Promise就是为了把JS复杂的嵌套转换成常人思维的线性代码。

// 就像下面这样:
// 你不在乎下面这三个ajax的执行顺序还好
// 如果你在乎顺序呢?
$.get('url', function(){
    
}, 'json');
$.get('url1', function(){
    
}, 'json');
$.get('url2', function(){
    
}, 'json');

// 就像这样?
$.get('url', function(){
    $.get('url1', function(){
        $.get('url2', function(){
    
        }, 'json');
    }, 'json');
}, 'json');


// 下面是我最近写的一段Node.js的代码
// 其实这个嵌套也不算多
// 如果业务逻辑相当复杂起来呢?
// 嵌套20 30层?
var adminIndex = function(params, callback){
  storeAdmin.getApiTokens(function(err, tokens){
    if ( err ) { callback(err); return; }
    storeAdmin.getApiServices(function(err, apiServices){
      if ( err ) { callback(err); return; }
      storeAdmin.getSocketioServices(function(err, socketioServices){
        if ( err ) { callback(err); return; }
        callback(0, {
          status : true,
          data : {
            api_tokens : tokens,
            api_services : apiServices,
            socketio_services : socketioServices
          }
        });
      });
    });
  });
};

说了这么多, 到底什么是Promise呢?

其实, Promise就是一个类,而且这个类已经成为ES6的标准,这个类目前在chrome32、Opera19、Firefox29以上的版本都已经支持了,要想在所有浏览器上都用上的话就看看es6-promise吧。

那Promise怎么用呢?

那看一段很简单的代码,请注意阅读代码中的注释。

var val = 1;

// 我们假设step1, step2, step3都是ajax调用后端或者是
// 在Node.js上查询数据库的异步操作
// 每个步骤都有对应的失败和成功处理回调
// 需求是这样,step1、step2、step3必须按顺序执行
function step1(resolve, reject) {
    console.log('步骤一:执行');
    if (val >= 1) {
        resolve('Hello I am No.1');
    } else if (val === 0) {
        reject(val);
    }
}

function step2(resolve, reject) {
    console.log('步骤二:执行');
    if (val === 1) {
        resolve('Hello I am No.2');
    } else if (val === 0) {
        reject(val);
    }
}

function step3(resolve, reject) {
    console.log('步骤三:执行');
    if (val === 1) {
        resolve('Hello I am No.3');
    } else if (val === 0) {
        reject(val);
    }
}

new Promise(step1)
    .then(function(val) {
        console.info(val);
        return new Promise(step2);
    })
    .then(function(val) {
        console.info(val);
        return new Promise(step3);
    })
    .then(function(val)  {
        console.info(val);
        return val;
    })
    .then(function(val) {
        console.info(val);
        return val;
    });

// 执行之后将会打印
步骤一:执行
Hello I am No.1
步骤二:执行
Hello I am No.2
步骤三:执行
Hello I am No.3
Hello I am No.3

Promise到底解决什么问题?

正如上面代码所示,个人认为Promise的意义就在于then链式调用,他避免了异步函数之间的层层嵌套,将原来异步函数的嵌套函数转变为便于阅读和理解的链式步骤关系

Promise的主要用法就是将各个异步操作封装成好多Promise,而一个Promise只处理一个异步操作。最后将各个Promise用链式调用写法串联,在这样处理下,如果异步逻辑之间前后关系很重的话,你也不需要层层嵌套,只需要把每个异步逻辑封装成Promise链式调用就可以了。

Promise常用的关键点

在Promise定义时,函数已经执行了

Promise构造函数只接受一个参数,即带有异步逻辑的函数,这个函数在new Promise时已经执行了。只不过在没有调用then之前不会resolve或reject

在then中的resolve方法中如何return?

在then方法中通常传递两个参数, 一个resolve函数, 一个reject函数(暂时不讨论,就是出错时运行的函数罢了)。resolve函数必须返回一个值才能把链式调用进行下去,而且这个值返回什么是有很大讲究的。

  • resolve返回一个新的Promise
    返回一个新Promise之后再调用的then就是新的Promise中的逻辑了。

  • resolve返回一个值
    返回一个值会传递到下一个then的resolve方法参数中。


learn_shifeng
452 声望16 粉丝

web前端